00001 #include <avr/io.h>
00002 #include <stdlib.h>
00003 #include <util/delay.h>
00004 #include <avr/interrupt.h>
00005 #include <avr/eeprom.h>
00006
00007
00008
00009 #define KEY_A 0x10 // switch on PB4
00010 #define KEY_B 0x20 // switch on PB5
00011 #define KEY_MODE 0x04 // swithc on PB2
00012
00013 #define TRUE 1
00014 #define FALSE 0
00015
00016 #define GAUGE_MAX 0x4C
00017 #define GAUGE_MIN 0x24
00018
00019
00020
00021 unsigned char speed = 16;
00022
00023 unsigned int EEMEM intensity[12] = {16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32};
00024 unsigned int EEMEM user_speed = 12;
00025 unsigned int EEMEM torch_status = 17;
00026
00027 unsigned char keybuffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
00028 unsigned char keybuffer_index = 0;
00029
00030
00031
00032
00033
00034 volatile unsigned char LED[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00035 unsigned char led_pwm = 0;
00036
00037
00038
00039
00040
00041 unsigned char pressed(unsigned char key)
00042 {
00043 unsigned char i, sum;
00044 sum = key;
00045 for(i=0; i<8; i++)
00046 {
00047 sum &= keybuffer[i];
00048 }
00049 if(sum > 0)
00050 return(TRUE);
00051 else
00052 return(FALSE);
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 void showDice(unsigned char dice, unsigned char eyes, unsigned char strength)
00073 {
00074 const unsigned int pat[2][6] = { {0x0002, 0x0080, 0x0082, 0x0180, 0x0182, 0x0185},
00075 {0x0020, 0x0200, 0x0220, 0x0a00, 0x0a20, 0x0650} };
00076 unsigned int j, m;
00077
00078 m=pat[dice][eyes];
00079 for(j=0; j<11; j++)
00080 {
00081 if(m & 0x01)
00082 LED[j] = eeprom_read_word(&intensity[j]);
00083 else
00084 LED[j] = 0;
00085 m=m>>1;
00086 }
00087 LED[11]=0;
00088 _delay_us(500);
00089 }
00090
00091
00092
00093 void idle(void)
00094
00095 {
00096 unsigned char i;
00097
00098 for(i=0; i<12; i++)
00099 LED[i]=eeprom_read_word(&intensity[i]);
00100 _delay_us(100);
00101 for(i=0; i<12; i++)
00102 LED[i] = 0;
00103 PRR=0x01;
00104 MCUCR |=(1<<SE);
00105 asm("SLEEP");
00106 PRR=0x00;
00107 while (!pressed(KEY_MODE))
00108 {
00109
00110 }
00111 _delay_us(100);
00112 }
00113
00114
00115
00116 void torch(void)
00117 {
00118 unsigned char strength = 17;
00119
00120 strength = eeprom_read_word(&torch_status);
00121
00122 while(!pressed(KEY_MODE))
00123 {
00124 if(pressed(KEY_A))
00125 {
00126 if(strength < 32)
00127 strength += 1;
00128 }
00129 LED[11] = strength;
00130 _delay_us(100);
00131
00132 if(pressed(KEY_B))
00133 {
00134 if (strength > 4)
00135 strength -= 1;
00136 }
00137 LED[11] = strength;
00138 _delay_us(100);
00139 }
00140 eeprom_write_word(&torch_status,strength);
00141 }
00142
00143
00144
00145
00146 void set_gauge(unsigned char level)
00147 {
00148 unsigned char i,tip;
00149 unsigned char rest;
00150
00151 if(level > GAUGE_MIN)
00152 {
00153 rest =GAUGE_MAX - level;
00154 tip = rest /7;
00155 for(i=0;i<=7;i++)
00156 {
00157 if(i < tip)
00158 LED[7-i] = 0;
00159 else if(i > tip)
00160 LED[7-i]=eeprom_read_word(&intensity[7-i]);
00161 }
00162 }
00163 else
00164 if(level < GAUGE_MIN)
00165 {
00166 tip=0;
00167 for(i=0;i<=7;i++)
00168 LED[i]=0;
00169 }
00170 else if(level > GAUGE_MAX)
00171 {
00172 for(i=0;i<=7;i++)
00173 LED[i] = eeprom_read_word(&intensity[i]);
00174 }
00175 }
00176
00177
00178
00179 void battery_gauge(void)
00180
00181 {
00182 ADMUX = 0x06;
00183 ADCSRB = (1<<ADLAR);
00184 ADCSRA = (1<<ADEN) | (1<<ADSC);
00185
00186 while(!pressed(KEY_MODE))
00187 {
00188 ADCSRA = (1<<ADEN) | (1<<ADSC);
00189 while(ADCSRA & (1<<ADSC));
00190 set_gauge(ADCH);
00191 _delay_us(100);
00192 }
00193 }
00194
00195
00196
00197 void dice_game(void)
00198 {
00199 unsigned int five_5=0x07A2;
00200 unsigned char i=0;
00201
00202 for(i=0;i<11;i++)
00203 {
00204 if(five_5 &0x01)
00205 LED[i]=eeprom_read_word(&intensity[i]);
00206 else
00207 LED[i]=0;
00208 five_5=five_5>>1;
00209 }
00210 _delay_us(10);
00211
00212 while(!pressed(KEY_MODE))
00213 {
00214 if(pressed(KEY_A))
00215 {
00216 showDice(1, (rand() % 6),32);
00217 }
00218 else if(pressed(KEY_B))
00219 {
00220 showDice(0,(rand() % 6),32);
00221 }
00222 i++;
00223 if(i>7) i=0;
00224 _delay_us(100);
00225 }
00226 }
00227
00228
00229
00230 void ritari_assa(void)
00231 {
00232 unsigned char i = 0;
00233 signed char act = 1, dir = 0;
00234 unsigned char disp[6] = {0, 0, 0, 0, 0, 0};
00235 unsigned char strength[6] = {32, 16, 8, 1, 0, 0};
00236
00237 speed =eeprom_read_word(&user_speed);
00238
00239 while(!pressed(KEY_MODE))
00240 {
00241 for(i=0;i<5;i++)
00242 disp[5-i] = disp[4-i];
00243 disp[0] = act;
00244 for(i=0;i<5;i++)
00245 LED[disp[5-i]] = strength[5-i];
00246 if(dir == 0)
00247 {
00248 if(++act > 5)
00249 dir = -1;
00250 }
00251 else
00252 {
00253 if(--act < 0)
00254 dir = 0;
00255 }
00256
00257 if(pressed(KEY_A))
00258 {
00259 if (speed < 128)
00260 speed = (speed << 1);
00261 }
00262 _delay_us(100);
00263
00264 if(pressed(KEY_B))
00265 {
00266 if (speed > 4)
00267 speed = (speed >> 1);
00268 }
00269 _delay_us(100);
00270
00271 for(i=0; i<speed; i++)
00272 _delay_us(100);
00273 }
00274 }
00275
00276
00277
00278 void twinkle(void)
00279 {
00280 unsigned char i, j = 2;
00281
00282 speed =eeprom_read_word(&user_speed);
00283 srand(TCNT1);
00284 while(!pressed(KEY_MODE))
00285 {
00286 for(i=0; i<12; i++)
00287 LED[i] = (LED[i] >> 1);
00288 if(--j == 0)
00289 {
00290 j = rand() % 11;
00291 if(LED[j] == 0)
00292 LED[j] = 32;
00293 j = (rand() >> 12) + 1;
00294 }
00295 }
00296 }
00297
00298
00299
00300 void initialise(void)
00301 {
00302 TCCR1A = 0x00;
00303 TCCR1B = 0x01;
00304 OCR1A = 0x00;
00305 OCR1B = 0x00;
00306 TIMSK1 = (1<< TOIE1);
00307 DDRA = 0x7f;
00308 DDRB = 0xcb;
00309 sei();
00310 }
00311
00312
00313 int main( void )
00314 {
00315 unsigned char i;
00316 unsigned char mode = 0;
00317
00318 initialise();
00319 while(1)
00320 {
00321 for(i=0;i<12;i++)
00322 LED[i] = 0;
00323 while(pressed(KEY_MODE))
00324 {
00325
00326 }
00327 switch(mode++)
00328 {
00329 case 0:
00330 idle();
00331 break;
00332 case 1:
00333 torch();
00334 break;
00335 case 2:
00336 battery_gauge();
00337 break;
00338 case 3:
00339 dice_game();
00340 break;
00341 case 4:
00342 ritari_assa();
00343 break;
00344 case 5:
00345 twinkle();
00346 break;
00347 }
00348 if(mode > 5)
00349 mode = 0;
00350 }
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void setLED(unsigned char led)
00363
00364 {
00365 switch(led)
00366 {
00367 case 0:
00368 PORTA = PINA & 0xfe;
00369 break;
00370 case 1:
00371 PORTA = PINA & 0xfd;
00372 break;
00373 case 2:
00374 PORTA = PINA & 0xfb;
00375 break;
00376 case 3:
00377 PORTA = PINA & 0xf7;
00378 break;
00379 case 4:
00380 PORTA = PINA & 0xef;
00381 break;
00382 case 5:
00383 PORTA = PINA & 0xdf;
00384 break;
00385 case 6:
00386 PORTA = PINA & 0xbf;
00387 break;
00388 case 7:
00389 PORTB = PINB & 0xfe;
00390 break;
00391 case 8:
00392 PORTB = PINB & 0xf7;
00393 break;
00394 case 9:
00395 PORTB = PINB & 0xbf;
00396 break;
00397 case 10:
00398 PORTB = PINB & 0x7f;
00399 break;
00400 case 11:
00401 PORTB = PINB & 0xfd;
00402 break;
00403 }
00404 }
00405
00406
00407
00408 void clearLED(unsigned char led)
00409 {
00410 switch(led)
00411 {
00412 case 0:
00413 PORTA = PINA | 0x01;
00414 break;
00415 case 1:
00416 PORTA = PINA | 0x02;
00417 break;
00418 case 2:
00419 PORTA = PINA | 0x04;
00420 break;
00421 case 3:
00422 PORTA = PINA | 0x08;
00423 break;
00424 case 4:
00425 PORTA = PINA | 0x10;
00426 break;
00427 case 5:
00428 PORTA = PINA | 0x20;
00429 break;
00430 case 6:
00431 PORTA = PINA | 0x40;
00432 break;
00433 case 7:
00434 PORTB = PINB | 0x01;
00435 break;
00436 case 8:
00437 PORTB = PINB | 0x08;
00438 break;
00439 case 9:
00440 PORTB = PINB | 0x40;
00441 break;
00442 case 10:
00443 PORTB = PINB | 0x80;
00444 break;
00445 case 11:
00446 PORTB = PINB | 0x02;
00447 break;
00448 }
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 ISR(TIM1_OVF_vect)
00458 {
00459 unsigned char i;
00460
00461
00462 keybuffer[keybuffer_index++] = ~PINB;
00463
00464 if(keybuffer_index > 7)
00465 keybuffer_index = 0;
00466
00467 if(led_pwm == 0)
00468 {
00469 for(i=0;i<12;i++)
00470 {
00471 if(LED[i] > 0)
00472 setLED(i);
00473 else
00474 clearLED(i);
00475 }
00476 }
00477 else
00478 {
00479 for(i=0;i<12;i++)
00480 {
00481 if(LED[i] == led_pwm)
00482 clearLED(i);
00483 }
00484 }
00485
00486 if(++led_pwm > 31)
00487 led_pwm = 0;
00488 }
00489